package cn.com.mdx.collection.queue;

import cn.com.mdx.collection.stack.ResizingArrayStack;

/**
 * <p> 栈队列，通过栈的方式来实现队列
 *
 * @author ：huangy
 * @date ：Created in 2020/8/13 5:01 下午
 */
public class StackQueue<Item> {

    /**
     * 容量
     */
    private int size;

    /**
     * 第一个栈
     */
    private final ResizingArrayStack<Item> stackOne;
    /**
     * 第二个栈
     */
    private final ResizingArrayStack<Item> stackTwo;

    public StackQueue() {
        stackOne = new ResizingArrayStack<>();
        stackTwo = new ResizingArrayStack<>();
    }

    /**
     * @param item 入队列数据
     * @return void
     * @Author huangy
     * @description //TODO 入队列
     * @date 5:16 下午 2020/8/12
     **/
    public void enqueue(Item item) {
        //如果一个栈为空，就往另一个栈中添加数据
        if (stackOne.isEmpty()) {
            stackCopy(stackTwo, stackOne);
            stackTwo.push(item);
        } else {
            stackCopy(stackOne, stackTwo);
            stackOne.push(item);
        }
        size++;
    }

    /**
     * @return Item 返回的数据
     * @Author huangy
     * @description //TODO 出队列
     * @date 5:17 下午 2020/8/12
     **/
    public Item dequeue() {
        if (isEmpty()) throw new UnsupportedOperationException("队列为空");
        size--;
        //将有数据的栈中的数据放入空栈中，将栈的数据进行一次颠倒
        if (stackOne.isEmpty()) {
            stackCopy(stackTwo, stackOne);
            return stackOne.pop();
        } else {
            stackCopy(stackOne, stackTwo);
            return stackTwo.pop();
        }
    }

    /**
     * @param stackOld 原栈
     * @param stackNew 新栈
     * @return void
     * @Author huangy
     * @description //TODO 将一个栈的数据倒入另一个栈中
     * @date 5:48 下午 2020/8/13
     **/
    private void stackCopy(ResizingArrayStack<Item> stackOld, ResizingArrayStack<Item> stackNew) {
        int stackSize = stackOld.size();
        for (int i = 0; i < stackSize; i++) stackNew.push(stackOld.pop());
    }

    /**
     * @return int
     * @Author huangy
     * @description //TODO 队列容量
     * @date 5:13 下午 2020/8/13
     **/
    public int size() {
        return size;
    }

    /**
     * @return boolean true 为空 false 不为空
     * @Author huangy
     * @description //TODO 队列是否空
     * @date 5:14 下午 2020/8/13
     **/
    private boolean isEmpty() {
        return size == 0;
    }

    public static void main(String[] args) {
        StackQueue<Integer> stackQueue = new StackQueue<>();
        stackQueue.enqueue(1);
        stackQueue.enqueue(2);
        stackQueue.enqueue(3);
        System.out.println(stackQueue.dequeue());
        stackQueue.enqueue(100);
        stackQueue.enqueue(101);
        stackQueue.enqueue(102);
        System.out.println("-----------------------------------");
        System.out.println(stackQueue.dequeue());
        System.out.println(stackQueue.dequeue());
        System.out.println(stackQueue.dequeue());
        System.out.println(stackQueue.dequeue());
        System.out.println(stackQueue.dequeue());
    }

}
